﻿// ———————————————————————–
// <copyright file="ClientCareType.cs" company="The MITRE Corporation">
//    Copyright (c) 2012 The MITRE Corporation. All rights reserved.
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//    http://www.apache.org/licenses/LICENSE-2.0
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
// </copyright>
// ———————————————————————–
/////////////////////////////////////////////////////////////////////////////////////////////////
// ClientCareType.cs - Library Class for the TEP Message
// Project: IC.NET - TEP Library
//
// Language:    C#, .NET 4.0
// Platform:    Windows 7, VS 2010 Beta 2
// Author:      Lizzie DeYoung MITRE
//              Brian Wilkins  MITRE

/////////////////////////////////////////////////////////////////////////////////////////////////

// Copyright (c) 2012 The MITRE Corporation. All rights reserved.
//
// NOTICE
// This software was produced for the U. S. Government
// under Contract No. FA8721-12-C-0001, and is
// subject to the Rights in Noncommercial Computer Software
// and Noncommercial Computer Software Documentation Clause
// (DFARS) 252.227-7014 (JUN 1995)using System;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using EDXLSharp.EDXLCTLib;

namespace EDXLSharp.EDXLTEPLib
{
  public class ClientCareType : IComposable
  {

    #region Private Member Variables

    private EDXLStringTypeWrapper clientCareRecordID;
    private EDXLDateTimeTypeWrapper clientCareRecordDateTime;
    private ValueKeyType triageStatus;
    private TriageStatusDefaultType triageStatusDefault;
    private ValueKeyType clientCurrentDisposition;
    private ClientCurrentDispositionDefaultType clientCurrentDispositionDefault;
    private EDXLStringTypeWrapper chiefComplaint;
    private IntegerWrapper systolicBloodPressure;
    private IntegerWrapper diastolicBloodPressure;
    private IntegerWrapper pulseRate;
    private IntegerWrapper respiratoryRate;
    private ValueListType cardiacMonitorRhythm;
    private EDXLStringTypeWrapper twelveLeadECGInterpretation;
    private IntegerWrapper co2Level;
    private IntegerWrapper bloodGlucoseLevel;
    private DegreesCTypeWrapper temperature;
    private IntegerWrapper totalGCS;
    private List<MedicationType> medicationAdministered;
    private List<ValueListType> proceduresPerformed;
    private ValueListType careProviderPrimaryImpression;
    private EDXLStringTypeWrapper seriousConcerns;
    private BooleanWrapper contaminationRadiationContagionStatus;
    private BooleanWrapper acsCDCFieldTraumaCriteria;
    private ValueKeyType contigencyMedicalSpecialtyCode;
    private ContigencyMedicalSpecialtyCodeDefaultType contigencyMedicalSpecialtyCodeDefault;

    private string DefaultElementName = "ClientCare";

    #endregion //Private Member Variables

    #region Constructors

    public ClientCareType()
    {
      this.medicationAdministered = new List<MedicationType>();
      this.proceduresPerformed = new List<ValueListType>();
    }

    #endregion // Constructors

    #region Public Accessors

    public EDXLStringTypeWrapper ClientCareRecordID
    {
      get { return this.clientCareRecordID; }
      set { this.clientCareRecordID = value; }
    }

    public EDXLDateTimeTypeWrapper ClientCareRecordDateTime
    {
      get { return this.clientCareRecordDateTime; }
      set { this.clientCareRecordDateTime = value; }
    }

    public ValueKeyType TriageStatus
    {
      get { return this.triageStatus; }
      set { this.triageStatus = value; }
    }

    public TriageStatusDefaultType TriageStatusDefault
    {
      get { return this.triageStatusDefault; }
      set { this.triageStatusDefault = value; }
    }

    public ValueKeyType ClientCurrentDisposition
    {
      get { return this.clientCurrentDisposition; }
      set { this.clientCurrentDisposition = value; }
    }

    public ClientCurrentDispositionDefaultType ClientCurrentDipositionDefault
    {
      get { return this.clientCurrentDispositionDefault; }
      set { this.clientCurrentDispositionDefault = value; }
    }

    public EDXLStringTypeWrapper ChiefComplaint
    {
      get { return this.chiefComplaint; }
      set { this.chiefComplaint = value; }
    }

    public IntegerWrapper SystolicBloodPressure
    {
      get { return this.systolicBloodPressure; }
      set { this.systolicBloodPressure = value; }
    }

    public IntegerWrapper DiastolicBloodPressure
    {
      get { return this.diastolicBloodPressure; }
      set { this.diastolicBloodPressure = value; }
    }

    public IntegerWrapper PulseRate
    {
      get { return this.pulseRate; }
      set { this.pulseRate = value; }
    }

    public IntegerWrapper RespiratoryRate
    {
      get { return this.respiratoryRate; }
      set { this.respiratoryRate = value; }
    }

    public ValueListType CardiacMonitorRhythm
    {
      get { return this.cardiacMonitorRhythm; }
      set { this.cardiacMonitorRhythm = value; }
    }

    public EDXLStringTypeWrapper TwelveLeadECGInterpretation
    {
      get { return this.twelveLeadECGInterpretation; }
      set { this.twelveLeadECGInterpretation = value; }
    }

    public IntegerWrapper CO2Level
    {
      get { return this.co2Level; }
      set { this.co2Level = value; }
    }

    public IntegerWrapper BloodGlucoseLevel
    {
      get { return this.bloodGlucoseLevel; }
      set { this.bloodGlucoseLevel = value; }
    }

    public DegreesCTypeWrapper Temperature
    {
      get { return this.temperature; }
      set { this.temperature = value; }
    }

    public IntegerWrapper TotalGCS
    {
      get { return this.totalGCS; }
      set { this.totalGCS = value; }
    }

    public List<MedicationType> MedicationAdministered
    {
      get { return this.medicationAdministered; }
      set { this.medicationAdministered = value; }
    }

    public List<ValueListType> ProceduresPerformed
    {
      get { return this.proceduresPerformed; }
      set { this.proceduresPerformed = value; }
    }

    public ValueListType CareProviderPrimaryImpression
    {
      get { return this.careProviderPrimaryImpression; }
      set { this.careProviderPrimaryImpression = value; }
    }

    public EDXLStringTypeWrapper SeriousConcerns
    {
      get { return this.seriousConcerns; }
      set { this.seriousConcerns = value; }
    }

    public BooleanWrapper ContaminationRadiationContagionStatus
    {
      get { return this.contaminationRadiationContagionStatus; }
      set { this.contaminationRadiationContagionStatus = value; }
    }

    public BooleanWrapper AcsCDCFieldTraumaCriteria
    {
      get { return this.acsCDCFieldTraumaCriteria; }
      set { this.acsCDCFieldTraumaCriteria = value; }
    }

    public ValueKeyType ContigencyMedicalSpecialtyCode
    {
      get { return this.contigencyMedicalSpecialtyCode; }
      set { this.contigencyMedicalSpecialtyCode = value; }
    }

    public ContigencyMedicalSpecialtyCodeDefaultType ContigencyMedicalSpecialtyCodeDefault
    {
      get { return this.contigencyMedicalSpecialtyCodeDefault; }
      set { this.contigencyMedicalSpecialtyCodeDefault = value; }
    }

    #endregion // Public Accessors

    #region Public Member Functions

    public void WriteXML(XmlWriter xwriter)
    {
      this.WriteXML(xwriter, this.DefaultElementName);
    }

    public void WriteXML(XmlWriter xwriter, string name)
    {
      this.Validate();

      xwriter.WriteStartDocument(false);
      xwriter.WriteStartElement(name);

      if (this.clientCareRecordID != null)
      {
        this.clientCareRecordID.WriteXML(xwriter, "clientCareRecordID");
      }

      if (this.clientCareRecordDateTime != null)
      {
        this.clientCareRecordDateTime.WriteXML(xwriter, "clientCareRecordDateTime");
      }

      if (this.triageStatus != null)
      {
        this.triageStatus.WriteXML(xwriter, "triageStatus");
      }

      if (this.triageStatusDefault != null)
      {
        this.triageStatusDefault.WriteXML(xwriter, "triageStatusDefault");
      }

      if (this.clientCurrentDisposition != null)
      {
        this.clientCurrentDisposition.WriteXML(xwriter, "clientCurrentDisposition");
      }

      if (this.clientCurrentDispositionDefault != null)
      {
        this.clientCurrentDispositionDefault.WriteXML(xwriter, "clientCurrentDispositionDefault");
      }

      if (this.chiefComplaint != null)
      {
        this.chiefComplaint.WriteXML(xwriter, "chiefComplaint");
      }

      if (this.systolicBloodPressure != null)
      {
        this.systolicBloodPressure.WriteXML(xwriter, "systolicBloodPressure");
      }

      if (this.diastolicBloodPressure != null)
      {
        this.diastolicBloodPressure.WriteXML(xwriter, "diastolicBloodPressure");
      }

      if (this.pulseRate != null)
      {
        this.pulseRate.WriteXML(xwriter, "pulseRate");
      }

      if (this.respiratoryRate != null)
      {
        this.respiratoryRate.WriteXML(xwriter, "respiratoryRate");
      }

      if (this.cardiacMonitorRhythm != null)
      {
        this.cardiacMonitorRhythm.WriteXML(xwriter, "cardiacMonitorRhythm");
      }

      if (this.twelveLeadECGInterpretation != null)
      {
        this.twelveLeadECGInterpretation.WriteXML(xwriter, "twelveLeadECGInterpretation");
      }

      if (this.CO2Level != null)
      {
        this.CO2Level.WriteXML(xwriter, "CO2Level");
      }

      if (this.bloodGlucoseLevel != null)
      {
        this.bloodGlucoseLevel.WriteXML(xwriter, "bloodGlucoseLevel");
      }

      if (this.temperature != null)
      {
        this.temperature.WriteXML(xwriter, "temperature");
      }

      if (this.totalGCS != null)
      {
        this.totalGCS.WriteXML(xwriter, "totalGCS");
      }

      if (this.medicationAdministered != null)
      {
        foreach (MedicationType val in this.medicationAdministered)
        {
          val.WriteXML(xwriter, "medicationAdministered");
        }
      }

      if (this.proceduresPerformed != null)
      {
        foreach (ValueListType val in this.proceduresPerformed)
        {
          val.WriteXML(xwriter, "proceduresPerformed");
        }
      }

      if (this.careProviderPrimaryImpression != null)
      {
        this.careProviderPrimaryImpression.WriteXML(xwriter, "careProviderPrimaryImpression");
      }

      if (this.seriousConcerns != null)
      {
        this.seriousConcerns.WriteXML(xwriter, "seriousConcerns");
      }

      if (this.contaminationRadiationContagionStatus != null)
      {
        this.contaminationRadiationContagionStatus.WriteXML(xwriter, "contaminationRadiationContagionStatus");
      }

      if (this.acsCDCFieldTraumaCriteria != null)
      {
        this.acsCDCFieldTraumaCriteria.WriteXML(xwriter, "acsCDCFieldTraumaCriteria");
      }

      if (this.contigencyMedicalSpecialtyCode != null)
      {
        this.contigencyMedicalSpecialtyCode.WriteXML(xwriter, "contigencyMedicalSpecialtyCode");
      }

      if (this.contigencyMedicalSpecialtyCodeDefault != null)
      {
        this.contigencyMedicalSpecialtyCodeDefault.WriteXML(xwriter, "contigencyMedicalSpecialtyCodeDefault");
      }

      xwriter.WriteEndElement();
    }

    public void ReadXML(XmlNode rootnode)
    {
      foreach (XmlNode node in rootnode)
      {
        if (String.IsNullOrEmpty(node.InnerText))
        {
          continue;
        }

        switch (node.LocalName)
        {
          case "clientCareRecordID":
            if (this.clientCareRecordID == null)
            {
              this.clientCareRecordID = new EDXLStringTypeWrapper();
            }
            this.clientCareRecordID.ReadXML(node);
            break;

          case "clientCareRecordDateTime":
            if (this.clientCareRecordDateTime == null)
            {
              this.clientCareRecordDateTime = new EDXLDateTimeTypeWrapper();
            }
            this.clientCareRecordDateTime.ReadXML(node);
            break;

          case "triageStatus":
            if (this.triageStatus == null)
            {
              this.triageStatus = new ValueKeyType();
            }
            this.triageStatus.ReadXML(node);
            break;

          case "triageStatusDefault":
            if (this.triageStatusDefault == null)
            {
              this.triageStatusDefault = new TriageStatusDefaultType();
            }
            this.triageStatusDefault.ReadXML(node);
            break;

          case "clientCurrentDisposition":
            if (this.clientCurrentDisposition == null)
            {
              this.clientCurrentDisposition = new ValueKeyType();
            }
            this.clientCurrentDisposition.ReadXML(node);
            break;

          case "clientCurrentDispositionDefault":
            if (this.clientCurrentDispositionDefault == null)
            {
              this.clientCurrentDispositionDefault = new ClientCurrentDispositionDefaultType();
            }
            this.clientCurrentDispositionDefault.ReadXML(node);
            break;

          case "chiefComplaint":
            if (this.chiefComplaint == null)
            {
              this.chiefComplaint = new EDXLStringTypeWrapper();
            }
            this.chiefComplaint.ReadXML(node);
            break;

          case "systolicBloodPressure":
            if (this.systolicBloodPressure == null)
            {
              this.systolicBloodPressure = new IntegerWrapper();
            }
            this.systolicBloodPressure.ReadXML(node);
            break;

          case "diastolicBloodPressure":
            if (this.diastolicBloodPressure == null)
            {
              this.diastolicBloodPressure = new IntegerWrapper();
            }
            this.diastolicBloodPressure.ReadXML(node);
            break;

          case "pulseRate":
            if (this.pulseRate == null)
            {
              this.pulseRate = new IntegerWrapper();
            }
            this.pulseRate.ReadXML(node);
            break;

          case "respiratoryRate":
            if (this.respiratoryRate == null)
            {
              this.respiratoryRate = new IntegerWrapper();
            }
            this.respiratoryRate.ReadXML(node);
            break;

          case "cardiacMonitorRhythm":
            if (this.cardiacMonitorRhythm == null)
            {
              this.cardiacMonitorRhythm = new ValueListType();
            }
            this.cardiacMonitorRhythm.ReadXML(node);
            break;

          case "twelveLeadECGInterpretation":
            if (this.twelveLeadECGInterpretation == null)
            {
              this.twelveLeadECGInterpretation = new EDXLStringTypeWrapper();
            }
            this.twelveLeadECGInterpretation.ReadXML(node);
            break;

          case "CO2Level":
            if (this.CO2Level == null)
            {
              this.CO2Level = new IntegerWrapper();
            }
            this.CO2Level.ReadXML(node);
            break;

          case "bloodGlucoseLevel":
            if (this.bloodGlucoseLevel == null)
            {
              this.bloodGlucoseLevel = new IntegerWrapper();
            }
            this.bloodGlucoseLevel.ReadXML(node);
            break;

          case "temperature":
            if (this.temperature == null)
            {
              this.temperature = new DegreesCTypeWrapper();
            }
            this.temperature.ReadXML(node);
            break;

          case "totalGCS":
            if (this.totalGCS == null)
            {
              this.totalGCS = new IntegerWrapper();
            }
            this.totalGCS.ReadXML(node);
            break;

          case "medicationAdministered":
            if (this.medicationAdministered == null)
            {
              this.medicationAdministered = new List<MedicationType>();
            }
            MedicationType newval = new MedicationType();
            this.medicationAdministered.Add(newval);
            break;

          case "proceduresPerformed":
            if (this.proceduresPerformed == null)
            {
              this.proceduresPerformed = new List<ValueListType>();
            }
            ValueListType newval1 = new ValueListType();
            this.proceduresPerformed.Add(newval1);
            break;

          case "careProviderPrimaryImpression":
            if (this.careProviderPrimaryImpression == null)
            {
              this.careProviderPrimaryImpression = new ValueListType();
            }
            this.careProviderPrimaryImpression.ReadXML(node);
            break;

          case "seriousConcerns":
            if (this.seriousConcerns == null)
            {
              this.seriousConcerns = new EDXLStringTypeWrapper();
            }
            this.seriousConcerns.ReadXML(node);
            break;

          case "contaminationRadiationContagionStatus":
            if (this.contaminationRadiationContagionStatus == null)
            {
              this.contaminationRadiationContagionStatus = new BooleanWrapper();
            }
            this.contaminationRadiationContagionStatus.ReadXML(node);
            break;

          case "acsCDCFieldTraumaCriteria":
            if (this.acsCDCFieldTraumaCriteria == null)
            {
              this.acsCDCFieldTraumaCriteria = new BooleanWrapper();
            }
            this.acsCDCFieldTraumaCriteria.ReadXML(node);
            break;

          case "contigencyMedicalSpecialtyCode":
            if (this.contigencyMedicalSpecialtyCode == null)
            {
              this.contigencyMedicalSpecialtyCode = new ValueKeyType();
            }
            this.contigencyMedicalSpecialtyCode.ReadXML(node);
            break;

          case "contigencyMedicalSpecialtyCodeDefault":
            if (this.contigencyMedicalSpecialtyCodeDefault == null)
            {
              this.contigencyMedicalSpecialtyCodeDefault = new ContigencyMedicalSpecialtyCodeDefaultType();
            }
            this.contigencyMedicalSpecialtyCodeDefault.ReadXML(node);
            break;
        }
      }

      this.Validate();
    }

    public void Validate()
    {
      if (this.clientCareRecordID == null)
      {
        throw new ArgumentNullException("A clientCareRecordID element is required. No null values.");
      }

      if (this.clientCareRecordDateTime == null)
      {
        throw new ArgumentNullException("A clientCareRecordDateTime element is required. No null values.");
      }

      if (this.triageStatus != null && this.triageStatusDefault != null)
      {
        throw new ArgumentException("One of triageStatus or triageStatusDefault must be used, not both.");
      }
      else if (this.triageStatus == null && this.triageStatusDefault == null)
      {
        throw new ArgumentException("One of triageStatus or triageStatusDefault must be used.");
      }

      if (this.clientCurrentDisposition != null && this.clientCurrentDispositionDefault != null)
      {
        throw new ArgumentException("One of clientCurrentDisposition or clientCurrentDispositionDefault must be used, not both.");
      }
      else if (this.clientCurrentDisposition == null && this.clientCurrentDispositionDefault == null)
      {
        throw new ArgumentException("One of clientCurrentDisposition or clientCurrentDispositionDefault must be used.");
      }

      if (this.systolicBloodPressure != null)
      {
        if (this.systolicBloodPressure.Value < 0 || this.systolicBloodPressure.Value > 300)
        {
          throw new ArgumentException("systolicBloodPressure must be between 0 and 300.");
        }
      }

      if (this.diastolicBloodPressure != null)
      {
        if (this.diastolicBloodPressure.Value < 0 || this.diastolicBloodPressure.Value > 300)
        {
          throw new ArgumentException("diastolicBloodPressure must be between 0 and 300.");
        }
      }

      if (this.pulseRate != null)
      {
        if (this.pulseRate.Value < 0 || this.pulseRate.Value > 320)
        {
          throw new ArgumentException("pulseRate must be between 0 and 320.");
        }
      }

      if (this.respiratoryRate != null)
      {
        if (this.respiratoryRate.Value < 0 || this.respiratoryRate.Value > 100)
        {
          throw new ArgumentException("this.respiratoryRate must be between 0 and 100.");
        }
      }

      if (this.bloodGlucoseLevel != null)
      {
        if (this.bloodGlucoseLevel.Value < 0 || this.bloodGlucoseLevel.Value > 500)
        {
          throw new ArgumentException("bloodGlucoseLevel must be between 0 and 500.");
        }
      }

      if (this.totalGCS != null)
      {
        if (this.totalGCS.Value < 3 || this.totalGCS.Value > 15)
        {
          throw new ArgumentException("totalGCS must be between 3 and 15.");
        }
      }

      if (this.contigencyMedicalSpecialtyCode != null && this.contigencyMedicalSpecialtyCodeDefault != null)
      {
        throw new ArgumentException("One of contigencyMedicalSpecialtyCode or contigencyMedicalSpecialtyCodeDefault must be used, not both.");
      }
      else if (this.contigencyMedicalSpecialtyCode == null && this.contigencyMedicalSpecialtyCodeDefault == null)
      {
        throw new ArgumentException("One of contigencyMedicalSpecialtyCode or contigencyMedicalSpecialtyCodeDefault must be used.");
      }
    }

    #endregion // Public Member Functions

    #region Private Member Functions
    #endregion // Private Member Functions
  }
}